home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1997 February / EnigmA AMIGA RUN 15 (1997)(G.R. Edizioni)(IT)[!][issue 1997-02][PLANET CD V].iso / enigma / earcd / emula / arosdv19.lha / AROS / devs / nil_handler.c < prev    next >
C/C++ Source or Header  |  1996-10-24  |  7KB  |  285 lines

  1. /*
  2.     (C) 1995-96 AROS - The Amiga Replacement OS
  3.     $Id: nil_handler.c,v 1.4 1996/10/24 15:50:21 aros Exp $
  4.     $Log: nil_handler.c,v $
  5.     Revision 1.4  1996/10/24 15:50:21  aros
  6.     Use the official AROS macros over the __AROS versions.
  7.  
  8.     Revision 1.3  1996/10/10 13:14:54  digulla
  9.     ? (Fleischer)
  10.  
  11.     Revision 1.2  1996/09/12 14:52:00  digulla
  12.     Use correct way to access external names (was missing)
  13.  
  14.     Revision 1.1  1996/09/11 12:52:54  digulla
  15.     Two new devices by M. Fleischer: RAM: and NIL:
  16.  
  17.     Desc:
  18.     Lang:
  19. */
  20. #include <exec/errors.h>
  21. #include <exec/resident.h>
  22. #include <exec/memory.h>
  23. #include <clib/exec_protos.h>
  24. #include <utility/tagitem.h>
  25. #include <dos/dosextens.h>
  26. #include <dos/filesystem.h>
  27. #include <clib/dos_protos.h>
  28. #include <aros/libcall.h>
  29. #ifdef __GNUC__
  30.     #include "nil_handler_gcc.h"
  31. #endif
  32.  
  33. static const char name[];
  34. static const char version[];
  35. static const APTR inittabl[4];
  36. static void *const functable[];
  37. struct nilbase *AROS_SLIB_ENTRY(init,nil_handler)();
  38. void AROS_SLIB_ENTRY(open,nil_handler)();
  39. BPTR AROS_SLIB_ENTRY(close,nil_handler)();
  40. BPTR AROS_SLIB_ENTRY(expunge,nil_handler)();
  41. int AROS_SLIB_ENTRY(null,nil_handler)();
  42. void AROS_SLIB_ENTRY(beginio,nil_handler)();
  43. LONG AROS_SLIB_ENTRY(abortio,nil_handler)();
  44. static const char end;
  45.  
  46. int nil_handler_entry(void)
  47. {
  48.     /* If the handler was executed by accident return error code. */
  49.     return -1;
  50. }
  51.  
  52. const struct Resident nil_handler_resident=
  53. {
  54.     RTC_MATCHWORD,
  55.     (struct Resident *)&nil_handler_resident,
  56.     (APTR)&end,
  57.     RTF_AUTOINIT,
  58.     1,
  59.     NT_DEVICE,
  60.     0,
  61.     (char *)name,
  62.     (char *)&version[6],
  63.     (ULONG *)inittabl
  64. };
  65.  
  66. static const char name[]="nil.handler";
  67.  
  68. static const char version[]="$VER: nil_handler 1.0 (8.6.96)\n\015";
  69.  
  70. static const APTR inittabl[4]=
  71. {
  72.     (APTR)sizeof(struct nilbase),
  73.     (APTR)functable,
  74.     NULL,
  75.     &AROS_SLIB_ENTRY(init,nil_handler)
  76. };
  77.  
  78. static void *const functable[]=
  79. {
  80.     &AROS_SLIB_ENTRY(open,nil_handler),
  81.     &AROS_SLIB_ENTRY(close,nil_handler),
  82.     &AROS_SLIB_ENTRY(expunge,nil_handler),
  83.     &AROS_SLIB_ENTRY(null,nil_handler),
  84.     &AROS_SLIB_ENTRY(beginio,nil_handler),
  85.     &AROS_SLIB_ENTRY(abortio,nil_handler),
  86.     (void *)-1
  87. };
  88.  
  89. AROS_LH2(struct nilbase *, init,
  90.  AROS_LHA(struct nilbase *, nilbase, D0),
  91.  AROS_LHA(BPTR,             segList, A0),
  92.        struct ExecBase *, sysBase, 0, nil_handler)
  93. {
  94.     AROS_LIBFUNC_INIT
  95.  
  96.     /* Store arguments */
  97.     nilbase->sysbase=sysBase;
  98.     nilbase->seglist=segList;
  99.     nilbase->dosbase=(struct DosLibrary *)OpenLibrary("dos.library",39);
  100.     if(nilbase->dosbase!=NULL)
  101.     return nilbase;
  102.  
  103.     return NULL;
  104.     AROS_LIBFUNC_EXIT
  105. }
  106.  
  107. AROS_LH3(void, open,
  108.  AROS_LHA(struct IOFileSys *, iofs, A1),
  109.  AROS_LHA(ULONG,              unitnum, D0),
  110.  AROS_LHA(ULONG,              flags, D0),
  111.        struct nilbase *, nilbase, 1, nil_handler)
  112. {
  113.     AROS_LIBFUNC_INIT
  114.     ULONG *dev;
  115.  
  116.     /* Get compiler happy */
  117.     unitnum=flags=0;
  118.  
  119.     /* I have one more opener. */
  120.     nilbase->device.dd_Library.lib_OpenCnt++;
  121.  
  122.     /* Mark Message as recently used. */
  123.     iofs->IOFS.io_Message.mn_Node.ln_Type=NT_REPLYMSG;
  124.  
  125.     dev=AllocMem(sizeof(ULONG),MEMF_PUBLIC|MEMF_CLEAR);
  126.     if(dev!=NULL)
  127.     {
  128.         iofs->IOFS.io_Unit=(struct Unit *)dev;
  129.         iofs->IOFS.io_Device=&nilbase->device;
  130.         nilbase->device.dd_Library.lib_Flags&=~LIBF_DELEXP;
  131.         iofs->IOFS.io_Error=0;
  132.         return;
  133.     }else
  134.     iofs->io_DosError=ERROR_NO_FREE_STORE;
  135.     
  136.     iofs->IOFS.io_Error=IOERR_OPENFAIL;
  137.     nilbase->device.dd_Library.lib_OpenCnt--;
  138.  
  139.     AROS_LIBFUNC_EXIT
  140. }
  141.  
  142. AROS_LH1(BPTR, close,
  143.  AROS_LHA(struct IOFileSys *, iofs, A1),
  144.        struct nilbase *, nilbase, 2, nil_handler)
  145. {
  146.     AROS_LIBFUNC_INIT
  147.     ULONG *dev;
  148.    
  149.     dev=(ULONG *)iofs->IOFS.io_Unit;
  150.     if(*dev)
  151.     {
  152.     iofs->io_DosError=ERROR_OBJECT_IN_USE;
  153.     return 0;
  154.     }
  155.  
  156.     /* Let any following attemps to use the device crash hard. */
  157.     iofs->IOFS.io_Device=(struct Device *)-1;
  158.     FreeMem(dev,sizeof(ULONG));
  159.     iofs->io_DosError=0;
  160.  
  161.     /* I have one fewer opener. */
  162.     if(!--nilbase->device.dd_Library.lib_OpenCnt)
  163.     {
  164.     /* Delayed expunge pending? */
  165.     if(nilbase->device.dd_Library.lib_Flags&LIBF_DELEXP)
  166.         /* Then expunge the device */
  167.         return expunge();
  168.     }
  169.     return 0;
  170.     AROS_LIBFUNC_EXIT
  171. }
  172.  
  173. AROS_LH0(BPTR, expunge, struct nilbase *, nilbase, 3, nil_handler)
  174. {
  175.     AROS_LIBFUNC_INIT
  176.  
  177.     BPTR ret;
  178.     /*
  179.     This function is single-threaded by exec by calling Forbid.
  180.     Never break the Forbid() or strange things might happen.
  181.     */
  182.  
  183.     /* Test for openers. */
  184.     if(nilbase->device.dd_Library.lib_OpenCnt)
  185.     {
  186.     /* Set the delayed expunge flag and return. */
  187.     nilbase->device.dd_Library.lib_Flags|=LIBF_DELEXP;
  188.     return 0;
  189.     }
  190.  
  191.     /* Free all resources */
  192.     CloseLibrary((struct Library *)nilbase->dosbase);
  193.  
  194.     /* Get rid of the device. Remove it from the list. */
  195.     Remove(&nilbase->device.dd_Library.lib_Node);
  196.  
  197.     /* Get returncode here - FreeMem() will destroy the field. */
  198.     ret=nilbase->seglist;
  199.  
  200.     /* Free the memory. */
  201.     FreeMem((char *)nilbase-nilbase->device.dd_Library.lib_NegSize,
  202.         nilbase->device.dd_Library.lib_NegSize+nilbase->device.dd_Library.lib_PosSize);
  203.  
  204.     return ret;
  205.     AROS_LIBFUNC_EXIT
  206. }
  207.  
  208. AROS_LH0I(int, null, struct nilbase *, nilbase, 4, nil_handler)
  209. {
  210.     AROS_LIBFUNC_INIT
  211.     return 0;
  212.     AROS_LIBFUNC_EXIT
  213. }
  214.  
  215. AROS_LH1(void, beginio,
  216.  AROS_LHA(struct IOFileSys *, iofs, A1),
  217.        struct nilbase *, nilbase, 5, nil_handler)
  218. {
  219.     AROS_LIBFUNC_INIT
  220.     LONG error=0;
  221.  
  222.     /*
  223.     Do everything quick no matter what. This is possible
  224.     because I never need to Wait().
  225.     */
  226.     switch(iofs->IOFS.io_Command)
  227.     {
  228.     case FSA_OPEN:
  229.     case FSA_OPEN_FILE:
  230.         /* No names allowed on NIL: */
  231.         if(((STRPTR)iofs->io_Args[0])[0])
  232.         {
  233.         error=ERROR_OBJECT_NOT_FOUND;
  234.         break;
  235.         }
  236.         Forbid();
  237.         ++*(ULONG *)iofs->IOFS.io_Unit;
  238.         Permit();
  239.         break;
  240.  
  241.     case FSA_READ:
  242.         iofs->io_Args[1]=0;
  243.         break;
  244.  
  245.     case FSA_WRITE:
  246.         break;
  247.  
  248.     case FSA_SEEK:
  249.         iofs->io_Args[0]=0;
  250.         iofs->io_Args[1]=0;
  251.         break;
  252.  
  253.     case FSA_CLOSE:
  254.         Forbid();
  255.         --*(ULONG *)iofs->IOFS.io_Unit;
  256.         Permit();
  257.         break;
  258.  
  259.     default:
  260.         error=ERROR_NOT_IMPLEMENTED;
  261.         break;
  262.     }
  263.  
  264.     /* Set error code */
  265.     iofs->io_DosError=error;
  266.  
  267.     /* If the quick bit is not set send the message to the port */
  268.     if(!(iofs->IOFS.io_Flags&IOF_QUICK))
  269.     ReplyMsg(&iofs->IOFS.io_Message);
  270.  
  271.     AROS_LIBFUNC_EXIT
  272. }
  273.  
  274. AROS_LH1(LONG, abortio,
  275.  AROS_LHA(struct IOFileSys *, iofs, A1),
  276.        struct nilbase *, nilbase, 6, nil_handler)
  277. {
  278.     AROS_LIBFUNC_INIT
  279.     /* Everything already done. */
  280.     return 0;
  281.     AROS_LIBFUNC_EXIT
  282. }
  283.  
  284. static const char end=0;
  285.